//
//  base.swift
//  touc
//
//  Created by z on 2020/6/26.
//  Copyright © 2020 z. All rights reserved.
//

import Foundation
class sendMapV {
    var data:bytes = bytes()
    var got = false
    var sendTime = 0;
}

class base {
    var dataSock = tcpSocket(-1)
    var numSock = tcpSocket(-1)
    var oneLen = 0
    var numPort = 0
    var dataPort = 0
    var wrietBuf = bytes()
    var wrietBuf2 = bytes()
    var key = con_key
    var sendPos:long = 0
    var peerPos:long = 0
    var recvPos:long = 0
    var packSendTime = con_packEffectTime;
    var lastPackCreateTime = getTime()
    var sendMap = [long:sendMapV]()
    
    var rNet = 0
    var wNet = 0
    var maxGotLen = 0
    var maxSenLen = 0
    
    var timeoutInter = con_timeoutInternal;
    var gotRate:Float = 1;
    var maxAskTime = 0
    var dataS = tcpSocket(-1)
    var numS = tcpSocket(-1)
    
    var lastRecvTime = getTime()
    
    init(_ oneLen_a:Int) {
        maxAskTime = calAskTime();
        sendMap[0]=sendMapV()
        oneLen = oneLen_a;
        iniSock();
    }
    
    func calAskTime()->Int {
        if (gotRate > 0.9){
            return 2;}
        if (gotRate > 0.75){
            return 3;}
        if (gotRate > 0.5){
            return 4;}
        if (gotRate > 0.25){
            return 5;}
        if (gotRate > 0.1){
            return 8;}
        return 20;
    }
    
    func reFreshSendMap() {
        if (sendMap[sendPos]?.data.count == 0)
        {return;}
        if (getTime() > lastPackCreateTime + packSendTime) {
            sendPos+=1;
            sendMap[sendPos] =  sendMapV()
            lastPackCreateTime = getTime();
        }
    }
    
    
    func dealFd(_ channel:Int, _ key:pollKey)  {
        if (channel == dataSock.fileno() && key.isReadable()){
            dealDataRecv();}
        else if (channel == dataSock.fileno() && key.isWritable()) {
            var n = dataSock.send(&wrietBuf)
            wNet += n
            wrietBuf.removeFirst(n)
        } else if (channel == numSock.fileno() && key.isWritable()) {
            var n = numSock.send(&wrietBuf2)
            wrietBuf2.removeFirst(n)
        }
    }
    
    func tellAddBuf(_ l:Int) {
        var b = bytes(repeating:4, count:4)
        structPack(4, long(l), &b)
        wrietBuf2 += b
    }
    
    func rig(_ s:selector )  {
        if (wrietBuf.count > 0)
        {
            s.register(dataSock.fileno(), POLLOUT|POLLIN)
        }
        else{
            s.register(dataSock.fileno(), POLLIN)
        }
        
        if (wrietBuf2.count > 0)
        {
            s.register(numSock.fileno(), POLLOUT)
        }
    }
    
    func calWaitTime()->long {
        if (sendMap[sendPos]?.data.count == 0){
            return timeoutInter;}
        var t = lastPackCreateTime + packSendTime - getTime();
        if (t > timeoutInter){
            return timeoutInter;}
        if (t <= 0){
            return 1;}
        return t;
    }
    
    func dealDataRecv()  {
        var r = dataSock.recv(tcpReadLen)
        rNet += r.count;
        if (r.count + (sendMap[sendPos]?.data.count)! >= oneLen){
            lastPackCreateTime = getTime();}
        var pos = 0;
        while (true) {
            var ll = oneLen - (sendMap[sendPos]?.data.count)!;
            if (r.count >= pos + ll) {
                self.sendMap[self.sendPos]?.data += r[pos..<pos+ll]
                pos += ll;
                sendPos+=1;
                sendMap[sendPos] =  sendMapV();
            } else {
                self.sendMap[self.sendPos]?.data += r[pos...]
                break;
            }
        }
    }
    
    func iniSock()  {
        dataS = tcpSocket()
      var r =  dataS.bind(("0.0.0.0",7777))
        dataS.listen(1)
        dataPort = dataS.getMyAdd().1
        numS = tcpSocket()
       r =  numS.bind(("0.0.0.0",7778))
        numS.listen(1)
        numPort = numS.getMyAdd().1
    }
    
    func doAccept()  {
        dataSock = dataS.accept().0;
        numSock = numS.accept().0;
        dataSock.setblocking(false);
        numSock.setblocking(false);
        print("conn");
    }
}
